package cn.iocoder.yudao.module.infra.controller.app.clouddisk;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.infra.api.deduplication.DeduplicationFileApi;
import cn.iocoder.yudao.module.infra.api.deduplication.dto.DeduplicationFileUploadReqDTO;
import cn.iocoder.yudao.module.infra.api.deduplication.dto.DeduplicationFileUploadRespDTO;
import cn.iocoder.yudao.module.infra.controller.app.clouddisk.vo.*;
import cn.iocoder.yudao.module.infra.dal.dataobject.clouddisk.UserCloudDiskDO;
import cn.iocoder.yudao.module.infra.service.clouddisk.UserCloudDiskService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;

/**
 * 用户云盘 APP Controller
 *
 * @author 芋道源码
 */
@Tag(name = "用户 APP - 云盘管理")
@RestController
@RequestMapping("/infra/cloud-disk")
@Validated
@Slf4j
public class AppUserCloudDiskController {

    @Resource
    private UserCloudDiskService userCloudDiskService;
    
    @Resource
    private DeduplicationFileApi deduplicationFileApi;

    @PostMapping("/upload")
    @Operation(summary = "上传文件到云盘")
    public CommonResult<AppUserCloudDiskRespVO> uploadFile(
            @RequestParam("file") MultipartFile file,
            @RequestParam(value = "parentId", required = false, defaultValue = "0") Long parentId,
            @RequestParam(value = "fileName", required = false) String fileName,
            @RequestParam(value = "enableCompress", required = false, defaultValue = "false") Boolean enableCompress,
            @RequestParam(value = "enableWatermark", required = false, defaultValue = "false") Boolean enableWatermark) throws Exception {
        
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        
        // 构建去重上传请求
        DeduplicationFileUploadReqDTO uploadReq = new DeduplicationFileUploadReqDTO();
        uploadReq.setName(fileName != null ? fileName : file.getOriginalFilename());
        uploadReq.setPath(generateCloudDiskPath(userId, parentId, uploadReq.getName()));
        uploadReq.setType(file.getContentType());
        uploadReq.setContentLength(file.getSize());
        uploadReq.setInputStream(file.getInputStream()); // 这会创建临时文件
        uploadReq.setConfigId(1L); // 默认配置
        
        // 设置处理选项
        if (enableCompress || enableWatermark) {
            DeduplicationFileUploadReqDTO.FileProcessingOptions processingOptions = 
                    new DeduplicationFileUploadReqDTO.FileProcessingOptions();
            processingOptions.setEnableCompress(enableCompress);
            processingOptions.setEnableWatermark(enableWatermark);
            uploadReq.setProcessingOptions(processingOptions);
        }
        
        // 设置云盘选项
        DeduplicationFileUploadReqDTO.CloudDiskOptions cloudDiskOptions =
                new DeduplicationFileUploadReqDTO.CloudDiskOptions();
        cloudDiskOptions.setSaveToCloudDisk(true);
        cloudDiskOptions.setParentId(parentId);
        cloudDiskOptions.setCloudFileName(uploadReq.getName());
        uploadReq.setCloudDiskOptions(cloudDiskOptions);
        
        // 执行上传
        DeduplicationFileUploadRespDTO uploadResult = deduplicationFileApi.uploadFile(uploadReq);
        
        // 保存到云盘
        AppUserCloudDiskCreateReqVO createReq = new AppUserCloudDiskCreateReqVO();
        createReq.setFileId(uploadResult.getFileId());
        createReq.setFileName(uploadResult.getName());
        createReq.setFileSize(uploadResult.getSize());
        createReq.setFileType(uploadResult.getType());
        createReq.setParentId(parentId);
        createReq.setFilePath(generateCloudDiskPath(userId, parentId, uploadResult.getName()));
        
        Long cloudDiskId = userCloudDiskService.createCloudDiskFile(userId, createReq);
        
        // 构建响应
        AppUserCloudDiskRespVO result = new AppUserCloudDiskRespVO();
        result.setId(cloudDiskId);
        result.setFileId(uploadResult.getFileId());
        result.setFileName(uploadResult.getName());
        result.setFileSize(uploadResult.getSize());
        result.setFileType(uploadResult.getType());
        result.setFileUrl(uploadResult.getUrl());
        result.setParentId(parentId);
        result.setIsFolder(false);
        result.setIsDuplicate(uploadResult.getIsDuplicate());
        result.setProcessingTaskId(uploadResult.getProcessingTaskId());
        
        return success(result);
    }

    @PostMapping("/create-folder")
    @Operation(summary = "创建文件夹")
    
    public CommonResult<AppUserCloudDiskRespVO> createFolder(@RequestBody @Valid AppUserCloudDiskCreateFolderReqVO reqVO) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        Long folderId = userCloudDiskService.createFolder(userId, reqVO);
        
        UserCloudDiskDO folder = userCloudDiskService.getCloudDiskFile(folderId);
        AppUserCloudDiskRespVO result = convertToRespVO(folder);
        
        return success(result);
    }

    @GetMapping("/list")
    @Operation(summary = "获取云盘文件列表")
    
    public CommonResult<List<AppUserCloudDiskRespVO>> getFileList(
            @RequestParam(value = "parentId", required = false, defaultValue = "0") Long parentId) {
        
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        List<UserCloudDiskDO> files = userCloudDiskService.getFileList(userId, parentId);
        
        List<AppUserCloudDiskRespVO> result = files.stream()
                .map(this::convertToRespVO)
                .collect(Collectors.toList());
        
        return success(result);
    }

    @GetMapping("/page")
    @Operation(summary = "分页获取云盘文件")
    
    public CommonResult<PageResult<AppUserCloudDiskRespVO>> getFilePage(AppUserCloudDiskPageReqVO reqVO) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        reqVO.setUserId(userId);
        
        PageResult<UserCloudDiskDO> pageResult = userCloudDiskService.getCloudDiskFilePage(reqVO);
        
        PageResult<AppUserCloudDiskRespVO> result = new PageResult<>(
                pageResult.getList().stream().map(this::convertToRespVO).collect(Collectors.toList()),
                pageResult.getTotal()
        );
        
        return success(result);
    }

    @GetMapping("/{id}")
    @Operation(summary = "获取云盘文件详情")
    @Parameter(name = "id", description = "云盘文件ID", required = true)
    
    public CommonResult<AppUserCloudDiskRespVO> getFile(@PathVariable("id") Long id) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        UserCloudDiskDO file = userCloudDiskService.getCloudDiskFile(id);
        
        // 检查权限
        if (file == null || !file.getUserId().equals(userId)) {
            return success(null);
        }
        
        AppUserCloudDiskRespVO result = convertToRespVO(file);
        return success(result);
    }

    @PutMapping("/{id}")
    @Operation(summary = "更新云盘文件")
    @Parameter(name = "id", description = "云盘文件ID", required = true)
    
    public CommonResult<Boolean> updateFile(@PathVariable("id") Long id, 
                                           @RequestBody @Valid AppUserCloudDiskUpdateReqVO reqVO) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        reqVO.setId(id);
        userCloudDiskService.updateCloudDiskFile(userId, reqVO);
        return success(true);
    }

    @DeleteMapping("/{id}")
    @Operation(summary = "删除云盘文件")
    @Parameter(name = "id", description = "云盘文件ID", required = true)
    
    public CommonResult<Boolean> deleteFile(@PathVariable("id") Long id) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        userCloudDiskService.deleteCloudDiskFile(userId, id);
        return success(true);
    }

    @PostMapping("/batch-delete")
    @Operation(summary = "批量删除云盘文件")
    
    public CommonResult<Integer> batchDeleteFiles(@RequestBody @Valid List<Long> ids) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        Integer deletedCount = userCloudDiskService.batchDeleteCloudDiskFiles(userId, ids);
        return success(deletedCount);
    }

    @PostMapping("/{id}/favorite")
    @Operation(summary = "收藏/取消收藏文件")
    @Parameter(name = "id", description = "云盘文件ID", required = true)
    
    public CommonResult<Boolean> toggleFavorite(@PathVariable("id") Long id) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        userCloudDiskService.toggleFavorite(userId, id);
        return success(true);
    }

    @GetMapping("/favorites")
    @Operation(summary = "获取收藏文件列表")
    
    public CommonResult<List<AppUserCloudDiskRespVO>> getFavorites() {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        List<UserCloudDiskDO> favorites = userCloudDiskService.getFavoriteFiles(userId);
        
        List<AppUserCloudDiskRespVO> result = favorites.stream()
                .map(this::convertToRespVO)
                .collect(Collectors.toList());
        
        return success(result);
    }

    @GetMapping("/search")
    @Operation(summary = "搜索云盘文件")
    
    public CommonResult<List<AppUserCloudDiskRespVO>> searchFiles(
            @RequestParam("keyword") String keyword,
            @RequestParam(value = "fileType", required = false) String fileType) {
        
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        List<UserCloudDiskDO> files = userCloudDiskService.searchFiles(userId, keyword, fileType);
        
        List<AppUserCloudDiskRespVO> result = files.stream()
                .map(this::convertToRespVO)
                .collect(Collectors.toList());
        
        return success(result);
    }

    @GetMapping("/stats")
    @Operation(summary = "获取云盘统计信息")
    
    public CommonResult<Map<String, Object>> getCloudDiskStats() {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        Map<String, Object> stats = userCloudDiskService.getCloudDiskStats(userId);
        return success(stats);
    }

    @PostMapping("/{id}/share")
    @Operation(summary = "分享文件")
    @Parameter(name = "id", description = "云盘文件ID", required = true)
    
    public CommonResult<String> shareFile(@PathVariable("id") Long id, 
                                         @RequestBody @Valid AppUserCloudDiskShareReqVO reqVO) {
        Long userId = SecurityFrameworkUtils.getLoginUserId();
        String shareCode = userCloudDiskService.shareFile(userId, id, reqVO);
        return success(shareCode);
    }

    @GetMapping("/share/{shareCode}")
    @Operation(summary = "访问分享文件")
    @Parameter(name = "shareCode", description = "分享码", required = true)
    public CommonResult<AppUserCloudDiskRespVO> getSharedFile(@PathVariable("shareCode") String shareCode) {
        UserCloudDiskDO file = userCloudDiskService.getSharedFile(shareCode);
        if (file == null) {
            return success(null);
        }
        
        AppUserCloudDiskRespVO result = convertToRespVO(file);
        return success(result);
    }

    // 私有方法
    
    private String generateCloudDiskPath(Long userId, Long parentId, String fileName) {
        return String.format("/cloud-disk/user-%d/parent-%d/%s", userId, parentId, fileName);
    }
    
    private AppUserCloudDiskRespVO convertToRespVO(UserCloudDiskDO cloudDisk) {
        AppUserCloudDiskRespVO result = new AppUserCloudDiskRespVO();
        result.setId(cloudDisk.getId());
        result.setFileId(cloudDisk.getFileId());
        result.setFileName(cloudDisk.getFileName());
        result.setFileSize(cloudDisk.getFileSize());
        result.setFileType(cloudDisk.getFileType());

        // 获取文件URL（如果是文件）
        if (!cloudDisk.getIsFolder() && cloudDisk.getFileId() != null) {
            try {
                cn.iocoder.yudao.module.infra.api.deduplication.dto.DeduplicationFileRespDTO fileInfo =
                        deduplicationFileApi.getFileInfo(cloudDisk.getFileId());
                if (fileInfo != null) {
                    result.setFileUrl(fileInfo.getUrl());
                }
            } catch (Exception e) {
                log.warn("[convertToRespVO][获取文件URL失败] fileId: {}", cloudDisk.getFileId(), e);
            }
        }

        result.setFilePath(cloudDisk.getFilePath());
        result.setParentId(cloudDisk.getParentId());
        result.setIsFolder(cloudDisk.getIsFolder());
        result.setIsFavorite(cloudDisk.getIsFavorite());
        result.setShareCode(cloudDisk.getShareCode());
        result.setShareExpireTime(cloudDisk.getShareExpireTime());
        result.setDownloadCount(cloudDisk.getDownloadCount());
        result.setViewCount(cloudDisk.getViewCount());
        result.setCreateTime(cloudDisk.getCreateTime());
        return result;
    }

}
